<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>噪声</title>
</head>
<body>
  <canvas width="512" height="512"></canvas>
  <script src="../common/lib/gl-renderer.js"></script>
  <script>
    const vertex = `
      attribute vec2 a_vertexPosition;
      attribute vec2 uv;

      varying vec2 vUv;

      void main() {
        gl_PointSize = 1.0;
        vUv = uv;
        gl_Position = vec4(a_vertexPosition, 1, 1);
      }
    `;

    const fragment = `
    #ifdef GL_ES
      precision highp float;
      #endif

      varying vec2 vUv;
      uniform float uTime;
      
      vec2 random2(vec2 st){
        st = vec2( dot(st,vec2(127.1,311.7)),
                  dot(st,vec2(269.5,183.3)) );
        return fract(sin(st) * 43758.5453123);
      }

      float seg_distance(in vec2 st, in vec2 a, in vec2 b) {
        vec3 ab = vec3(b - a, 0);
        vec3 p = vec3(st - a, 0);
        float l = length(ab);
        float d = abs(cross(p, normalize(ab)).z);
        float proj = dot(p, ab) / l;
        if(proj >= 0.0 && proj <= l) return d;
        return min(distance(st, a), distance(st, b));
      }

      void main() {
        vec2 st = vUv * 10.0;

        float d = 0.0;
        vec2 i_st = floor(st);
        vec2 f_st = fract(st);

        // vec2 p = random2(i_st);
        // d = distance(f_st, p);

        vec2 p0 = random2(i_st);

        for(int i = -1; i <= 1; i++) {
          for(int j = -1; j <= 1; j++) {
            if(i == 0 && j == 0) continue;
            vec2 neighbor = vec2(float(i), float(j));
            vec2 p = random2(i_st + neighbor);
            p = 0.5 + 0.5 * sin(uTime + 6.2831 * p);
            d += step(seg_distance(f_st, p0, neighbor + p), 0.03);
          }
        }

        gl_FragColor.rgb = vec3(d);
        gl_FragColor.a = 1.0;
      }
    `;

    const canvas = document.querySelector('canvas');
    const renderer = new GlRenderer(canvas);

    // load fragment shader and createProgram
    const program = renderer.compileSync(fragment, vertex);
    renderer.useProgram(program);
    renderer.uniforms.uTime = 0.0;

    requestAnimationFrame(function update(t) {
      renderer.uniforms.uTime = 0.001 * t;
      requestAnimationFrame(update);
    });

    renderer.setMeshData([{
      positions: [
        [-1, -1],
        [-1, 1],
        [1, 1],
        [1, -1],
      ],
      attributes: {
        uv: [
          [0, 0],
          [0, 1],
          [1, 1],
          [1, 0],
        ],
      },
      cells: [[0, 1, 2], [2, 0, 3]],
    }]);

    renderer.render();
  </script>
</body>
</html>